<template>
    <div class="page_root" :key="queryUpdateFlag" data-page-name="1" data-page-identification="x_hb0xe6o0k2">
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_q2pj193dfc 自定义模板_7xu4mdl9mj -->
            <!--          配置-->
            <a-modal :visible="state.settingVisible" title="配置" centered @ok="confirmSetting" @cancel="cancelSetting">
                <div class="setting-div">
                    <p> 配置自动下发时间后则每日按时自动下发 </p>

                    <p> 如未配置自动下发时间，仅支持手动点击下发按钮进行人工下发 </p>
                </div>
                <a-form-item label="自动下发时间">
                    <a-time-picker style="width: 100%" v-model:value="state.settingDate" value-format="HH:mm:ss" />
                </a-form-item>
            </a-modal>
            <!--          配置-->
            <!--          预览-->
            <a-modal
                :visible="state.showImgVisible"
                title="预览"
                centered
                :footer="null"
                width="80%"
                @cancel="state.showImgVisible = false"
                :mask-closable="false"
                :body-style="{
                    padding: '0'
                }"
            >
                <div style="height: 850px; overflow-y: auto">
                    <a-image
                        v-for="(item, index) in state.yqImage"
                        @click="imageChange"
                        width="100%"
                        :src="item.src"
                        :preview="false"
                    />
                </div>
            </a-modal>
            <!--          预览-->
            <a-modal
                :visible="state.changeDataVisible"
                title="修改原因"
                centered
                @ok="confirmReason"
                @cancel="cancelReason"
            >
                <a-textarea v-model:value="state.changeReason" :rows="4" :maxlength="30" show-count />
            </a-modal>
            <a-modal
                :visible="state.descriptionVisible"
                title="描述"
                centered
                @ok="confirmDescription"
                @cancel="cancelDescription"
            >
                <a-textarea :rows="4" v-model:value="state.changeDescription" />
            </a-modal>
            <div class="body">
                <div class="title" style="border: none; margin: 0; height: ">
                    <div class="top-title-first"></div>
                    <a-space>
                        <a-button
                            type="primary"
                            @click="handleIssued"
                            v-permission="'3000000862_vid_1e7ee3z8eo'"
                            :loading="state.downLoading"
                            >下发</a-button
                        >
                        <a-button type="primary" v-permission="'3000000862_vid_47bhwa63ai'" @click="handleSetting"
                            >配置</a-button
                        >
                        <a-button
                            type="primary"
                            v-permission="'3000000862_vid_g87nj7g2so'"
                            @click="handleShowDescription"
                            >描述</a-button
                        >
                        <a-button type="primary" ghost @click="refreshData">刷新</a-button>
                    </a-space>
                </div>
                <a-spin :spinning="state.spining" tip="加载中...">
                    <div class="title-margin">
                        <div class="ms-img"></div>
                        描述
                    </div>
                    <div class="description">{{ state.desciption }}</div>

                    <div class="scroll-content">
                        <div class="title">
                            <div class="top-title">水泥配料项目群日报-01 项目总体进展(1)</div>
                        </div>
                        <div class="img-body">
                            <a-image @click="imageChange" :width="state.jzWidth" :src="state.jzOne" :preview="false">
                                <template #placeholder>
                                    <a-spin />
                                </template>
                            </a-image>
                        </div>
                        <div class="title">
                            <div class="top-title">水泥配料项目群日报-01 项目总体进展(2)</div>
                        </div>
                        <div class="img-body">
                            <a-image @click="imageChange" :width="state.jzWidth" :src="state.jzTwo" :preview="false" />
                        </div>
                        <div class="title">
                            <div class="top-title">水泥配料项目群日报-01 项目总体进展(3)</div>
                        </div>
                        <div class="img-body">
                            <a-image
                                @click="imageChange"
                                :width="state.jzWidth"
                                :src="state.jzThree"
                                :preview="false"
                            />
                        </div>
                        <div class="title">
                            <div class="top-title">水泥配料项目群日报-02 延期项目</div>
                            <a-space>
                                <div>表头含下划线的字段支持双击表格编辑详细内容</div>
                                <a-button type="primary" @click="handleShowImg" :loading="state.ylLoading"
                                    >预览</a-button
                                >
                                <a-button type="primary" :loading="state.saveLoading" @click="handleSaveTable"
                                    >保存</a-button
                                >
                            </a-space>
                        </div>
                        <div class="default-table">
                            <a-table
                                :columns="columns"
                                row-key="projectId"
                                :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
                                :scroll="{ x: 'max-content', y: 520 }"
                                :data-source="state.tableData"
                                :pagination="false"
                                bordered
                                @resizeColumn="handleResizeColumn"
                            >
                                <template #headerCell="{ column, title }">
                                    <template v-if="title == '原因说明'">
                                        <div class="text-line-div">{{ title }}</div>
                                    </template>
                                </template>

                                <template #bodyCell="{ record, text, column }">
                                    <template v-if="column.dataIndex === 'opration'">
                                        <a-button type="link" size="small" @click="showEdit(record)">编辑</a-button>
                                        <a-popconfirm title="确定要删除吗？" @confirm="handleDeleteFaq(record)">
                                            <a-button type="link" size="small">删除</a-button>
                                        </a-popconfirm>
                                        <a-button type="link" size="small" @click="showPraise(record)">点赞</a-button>
                                    </template>
                                    <template v-if="column.dataIndex === 'reason'">
                                        <div class="db-click" @dblclick="changeData(record)">{{ text || '--' }}</div>
                                    </template>
                                </template>
                            </a-table>
                        </div>
                        <div class="title">
                            <div class="top-title">水泥配料项目群日报-03 项目问题&风险</div>
                        </div>
                        <div class="img-body" v-for="(item, index) in state.wtfxImg" :key="index">
                            <a-image @click="imageChange" :width="state.jzWidth" :src="item.src" :preview="false" />
                        </div>
                    </div>
                </a-spin>
            </div>
            <!-- end vid_q2pj193dfc 自定义模板_7xu4mdl9mj -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated,
        nextTick
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'

    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'

    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    import { nextTick } from 'vue'

    onMounted(() => {
        getData()
        getProgress()
    })

    function refreshData() {
        getData()
        getProgress()
    }

    function getData() {
        get('/solution-ppm/api/v2/built-in-system-ppm/delay_project/search').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.tableData = data.data.delayProjectList
            let yq = data.data.delayProjectIndexDetailList?.find(item => (item.name = '延期项目总数'))
            state.delayCount = yq
            state.projectData = data.data.delayProjectIndexDetailList?.filter(item => item.name !== '延期项目总数')
            state.selectedRowKeys = data.data.projectIdList
        })
        get('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/report_desc').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.desciption = data.data.configValue
        })
    }

    // 获取进展三张图
    function getProgress() {
        state.spining = true
        Promise.all([
            get('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/one'),
            get('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/second'),
            get('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/three'),
            get('/solution-ppm/api/v2/built-in-system-ppm/project_question/image_base64')
        ])
            .then(([oneData, secondData, thirdData, fourthData]) => {
                state.jzOne = `data:image/png;base64,${oneData.data[0]}`
                state.jzTwo = `data:image/png;base64,${secondData.data[0]}`
                state.jzThree = `data:image/png;base64,${thirdData.data[0]}`
                state.wtfxImg = fourthData.data.map(item => {
                    return {
                        src: `data:image/png;base64,${item[0]}`,
                        md5: item[1]
                    }
                })

                state.spining = false // 请求完成
            })
            .catch(error => {
                state.spining = false // 请求完成
                message.error(error)
            })
    }

    const columns = ref([
        {
            title: '区域',
            ellipsis: true,
            resizable: true,
            dataIndex: 'areaName',
            align: 'center'
        },
        {
            title: '项目名称',
            ellipsis: true,
            resizable: true,
            dataIndex: 'projectName',
            align: 'center'
        },
        {
            title: '项目经理',
            ellipsis: true,
            width: 100,
            resizable: true,
            dataIndex: 'pmName',
            align: 'center'
        },
        {
            title: 'PMO',
            ellipsis: true,
            width: 100,
            resizable: true,
            dataIndex: 'pmo',
            align: 'center'
        },
        {
            title: '项目阶段',
            ellipsis: true,
            resizable: true,
            dataIndex: 'milepostName',
            align: 'center'
        },
        {
            title: '计划完成时间',
            ellipsis: true,
            resizable: true,
            width: 150,
            dataIndex: 'planEndTime',
            align: 'center'
        },
        {
            title: '预计完成时间',
            ellipsis: true,
            resizable: true,
            width: 150,
            dataIndex: 'expectEndTime',
            align: 'center'
        },
        {
            title: '延期天数',
            ellipsis: true,
            width: 100,
            resizable: true,
            dataIndex: 'delay',
            align: 'center'
        },
        {
            title: '原因说明',
            resizable: true,
            dataIndex: 'reason',
            width: 400,
            align: 'center'
        }
    ])
    const state = reactive({
        tableData: [],
        projectData: [],
        downLoading: false,
        descriptionVisible: false,
        description: undefined,
        delayCount: {},
        changeDataVisible: false,
        changeReason: undefined,
        settingVisible: false,
        showImgVisible: false,
        settingDate: undefined,
        isLoading: false,
        ylLoading: false,
        saveLoading: false,
        spining: false,
        jzOne: '',
        jzWidth: '100%',
        jzTwo: '',
        jzThree: '',
        yqImage: [],
        wtfxImg: [],
        descrition: undefined,
        changeDescription: undefined,
        selectedRowKeys: []
    })

    function handlerGetSpace(data) {
        return data ? data.split(/[,，]/).map(item => item.trim()) : []
    }

    function confirmDescription() {
        post('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/report_desc', {
            'configKey': 'over_all_desc',
            'configValue': state.changeDescription
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            state.descriptionVisible = false
            getData()
        })
    }
    const onSelectChange = selectedRowKeys => {
        state.selectedRowKeys = selectedRowKeys
    }
    function cancelDescription() {
        state.descriptionVisible = false
    }

    function handleShowImg() {
        state.ylLoading = true
        get('/solution-ppm/api/v2/built-in-system-ppm/delay_project/image_base64')
            .then(data => {
                state.yqImage = data.data.map(item => {
                    return {
                        src: `data:image/png;base64,${item[0]}`,
                        md5: item[1]
                    }
                })
                state.showImgVisible = true
            })
            .finally(() => {
                state.ylLoading = false
            })
    }
    // 保存勾选
    function handleSaveTable() {
        state.saveLoading = true

        put('/solution-ppm/api/v2/built-in-system-ppm/delay_project/modify_status', state.selectedRowKeys)
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
                getData()
            })
            .finally(() => {
                state.saveLoading = false
            })
    }
    const handleIssued = async () => {
        state.downLoading = true

        get('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/dispatch')
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
            })
            .finally(() => {
                state.downLoading = false
            })
    }

    function handleSetting() {
        get('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/config ').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.settingVisible = true
            state.settingDate = data.data.configValue
        })
    }

    function handleShowDescription() {
        state.descriptionVisible = true
        state.changeDescription = state.desciption
    }

    function confirmSetting() {
        post('/solution-ppm/api/v2/built-in-system-ppm/over_all_progress/config ', {
            'configKey': 'report_group_scheduler_time',
            'configValue': state.settingDate
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            state.settingVisible = false
            state.settingDate = undefined
        })
    }

    function cancelSetting() {
        state.settingVisible = false
        state.settingDate = undefined
    }

    const currentData = ref({})

    function changeData(record) {
        currentData.value = record
        state.changeReason = cloneDeep(record.reason)
        state.changeDataVisible = true
    }

    function confirmReason() {
        currentData.value.reason = state.changeReason
        put('/solution-ppm/api/v2/built-in-system-ppm/delay_project/modify', currentData.value).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            state.changeDataVisible = false
            state.changeReason = undefined
            currentData.value = {}
            getData()
        })
    }

    function cancelReason() {
        state.changeDataVisible = false
        state.changeReason = undefined
        currentData.value = {}
    }

    const overStyle = ref({
        maxWidth: '300px',
        fontSize: '16px'
    })

    function handleResizeColumn(w, col) {
        if (col.title == '原因说明') {
            let div = document.querySelector('.omit-div')
            let width = w - 50
            div.style.width = width + 'px'
            overStyle.value.maxWidth = width + 'px'
        }

        col.width = w
    }

    function imageChange() {
        nextTick(() => {
            // 在 DOM 更新后强制应用样式
            const element = document.querySelectorAll('.ant3-image-preview-img-wrapper')
            const div = document.querySelectorAll('.ant3-image-preview-img')
            // console.log(element)
            if (element.length > 0) {
                element.forEach(item => {
                    item.style.position = 'relative'
                    item.style.left = '10%'
                })
            }
            if (div.length > 0) {
                element.forEach(item => {
                    item.style.width = '80%'
                })
            }
        })
    }
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }

    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }

    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }

    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }

    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }

    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }

    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }

    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }

    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }

    /*样式*/
    .default-table:deep(.@{ant-prefix}-table-thead) > tr > th {
        background-color: #3875ff;
        color: #fff;
        font-weight: 600;
        padding: 8px 16px;
        border-right: 1px solid #d9d9d9;
    }

    .default-table :deep(.@{ant-prefix}-table-tbody) tr > td {
        font-size: 14px;
        font-family: arial, helvetica, 'microsoft yahei';
        font-weight: 400;
        color: #595959;
        border-bottom: 1px solid #d9d9d9;
        padding: 8px 16px;
        word-break: break-all;

        .cell-wrapper {
            padding: 0 16px;
        }
    }

    .default-table :deep(.ant3-table-wrapper) {
        border-bottom: 1px solid #d9d9d9;
    }

    .top-title {
        height: 16px;
        padding-left: 8px;
        border-left: 4px solid #3875ff;
        font-size: 16px;
        line-height: 16px;
        color: #262626;
        font-weight: 600;
    }

    .top-title-first {
        height: 16px;
        font-size: 16px;
        line-height: 16px;
        color: #262626;
        font-weight: 600;
    }

    /*样式*/
    .title {
        justify-content: space-between;
        display: flex;
        margin-bottom: 16px;
        align-items: center;
        font-weight: bold; /* 标题加粗 */
        height: 70px;
        border-bottom: 1px solid #d9d9d9;
    }

    .content {
        display: flex;
        gap: 16px;
        margin-bottom: 16px;
    }

    .left {
        width: 100%;
    }

    .right {
        flex: 1;
    }

    .description {
        padding: 12px 16px;
        border: 1px solid #d9d9d9;
        word-wrap: break-word; /* 强制换行 */
        overflow-wrap: break-word; /* 支持较旧浏览器 */
        white-space: pre-wrap; /* 保持换行符 */
        max-height: 80px;
        min-height: 80px;
        overflow: auto;
        border-radius: 4px;
    }

    .body {
        background-color: #fff;
        padding: 24px;
        padding-top: 0;
    }

    .title-margin {
        display: flex;
        align-items: center;
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        margin-bottom: 13px;
    }

    .left-content {
        width: 100%; /* 大 div 的宽度 */
        height: 80px;
        display: flex;
        gap: 8px;
    }

    .scroll-container {
        padding: 16px 0px;
        flex: 1;
        display: inline-flex; /* 使用 inline-flex 确保横向排列 */
        white-space: nowrap; /* 防止换行 */
        height: 100%;
        overflow: auto;
        background: #ebf1ff;
        border: 1px solid #3875ff;
        border-radius: 4px;
    }

    .content-item {
        width: 125px;
        display: inline-block; /* 保证小 div 不换行 */
        border-right: 1px solid #a4c0ff; /* 边框样式 */
        box-sizing: border-box; /* 包括内边距和边框在内的宽度计算 */
        padding: 0 10px;
    }

    .content-item:last-child {
        border: none;
    }

    .number {
        text-align: center;
        font-size: 20px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 500;
        height: 24px;
        line-height: 24px;
    }

    .title-content {
        height: 24px;
        line-height: 24px;
        width: 100%;
        text-align: center; /* 如果希望文字居中显示 */
        font-size: 14px;
        color: #595959;
        letter-spacing: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        display: block;
    }

    .scroll-container::-webkit-scrollbar {
        height: 4px; /* 设置滚动条的高度 */
    }

    .zb-img,
    .ms-img {
        margin-right: 4px;
        width: 16px;
        height: 16px;
    }

    .zb-img {
        background-image: url('http://10.40.0.33:9001/file-storage/471954287738396672-source.png');
        background-size: cover;
    }

    .ms-img {
        background-image: url('http://10.40.0.33:9001/file-storage/471954302355546112-source.png');
        background-size: cover;
    }

    .yq-div {
        flex-direction: column; /* 确保子元素纵向排列 */
        padding: 16px;
        width: 120px;
        background: #ebf1ff;
        border: 1px solid #3875ff;
        border-radius: 4px;
        display: flex;
    }

    .text-line-div {
        text-decoration: underline;
        position: relative;
    }

    .db-click {
        cursor: pointer;
    }

    .red-color {
        color: #f5222d;
    }

    .omit-div {
        width: 320px;
        padding: 0 8px;
        min-height: 20px;
        height: 120px;
        white-space: pre-wrap;
        word-wrap: break-word;
        cursor: pointer;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 4; /* 显示行数 */
        -webkit-box-orient: vertical;
    }

    .img-jz {
        width: 100%;
        height: 300px;
    }

    .setting-div {
        color: #262626;
    }

    .scroll-content {
        height: calc(100vh - 350px);
        overflow-y: auto;
    }

    .page_root {
        overflow: hidden;
    }

    .title-margin {
        display: flex;
        align-items: center;
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        margin-bottom: 13px;
    }

    .description {
        padding: 12px 16px;
        border: 1px solid #d9d9d9;
        word-wrap: break-word; /* 强制换行 */
        overflow-wrap: break-word; /* 支持较旧浏览器 */
        white-space: pre-wrap; /* 保持换行符 */
        max-height: 80px;
        min-height: 80px;
        overflow: auto;
        border-radius: 4px;
    }

    .img-body {
        display: flex;
        justify-content: center;
    }
</style>
